#ifndef MISDATOS_H_
#include "MisDatos.h"
#define MISDATOS_H_

MisDatos::MisDatos(){

}


void MisDatos::inicializarArchivo1(std::string path, int longitudBloque, bool tieneBuffer, int longitudBuffer, bool tieneIndice, TipoIndice tipo, int longitudBloqueIndice) throw (ExcepcionMisDatos){
	enumIndice indice;
	enumRecurso recurso;
	enumAlmacenamiento almacenamiento = BLOQUES;
	
	if(tieneBuffer)
		recurso = ESCRITURA_DIRECTA;
	else
		recurso = UN_ALMACENAMIENTO;
	
		
	if(tieneIndice){
		if(tipo == ARBOL)
			indice = BSHARP;
		else
			indice = HASH_EXTENSIBLE;
	} else {
		indice = NO_INDEXADO;
	}
		
	this->recurso = FabricaDeRecursosDeAlmacenamiento::CrearRecursoAlmacenamiento(indice, recurso, almacenamiento, path, longitudBuffer, longitudBloqueIndice, longitudBloque);
} 

void MisDatos::inicializarArchivo2(std::string path, bool tieneBuffer, int longitudBuffer, bool tieneIndice, TipoIndice tipo, int longitudBloqueIndice) throw (ExcepcionMisDatos){
	enumIndice indice;
	enumRecurso recurso;
	enumAlmacenamiento almacenamiento = REGISTROS;
	
	if(tieneBuffer)
		recurso = ESCRITURA_DIRECTA;
	else
		recurso = UN_ALMACENAMIENTO;
		
	if(tieneIndice){
		if(tipo == ARBOL)
			indice = BSHARP;
		else
			indice = HASH_EXTENSIBLE;
	} else {
		indice = NO_INDEXADO;
	}
		
	this->recurso = FabricaDeRecursosDeAlmacenamiento::CrearRecursoAlmacenamiento(indice, recurso, almacenamiento, path, longitudBuffer, longitudBloqueIndice, 0);
}

void MisDatos::inicializarArchivo3(std::string path) throw (ExcepcionMisDatos){
	this->recurso = FabricaDeRecursosDeAlmacenamiento::CrearRecursoAlmacenamiento(NO_INDEXADO, UN_ALMACENAMIENTO, TEXTO, path, 0, 0, 0);
}

void MisDatos::agregarRegistroArchivo1(MiRegistroVariable registro) throw (ExcepcionMisDatos){
	RegistroVariable* nuevoRegistro = new RegistroVariable();
	nuevoRegistro->addCampo(registro.getMiStringID(), true);
	nuevoRegistro->Registro::addCampo(registro.getMiInt(), false);
	nuevoRegistro->addCampo(registro.getMiLista(), registro.getCantidadElementosLista());
	
	try{
		this->recurso.almacenar(*nuevoRegistro);
	} catch (int) {
		throw ExcepcionMisDatos("");
	}
	delete nuevoRegistro;
}

void MisDatos::agregarRegistroArchivo2(MiRegistroFijo registro) throw (ExcepcionMisDatos){
	
	RegistroFijo* nuevoRegistro = new RegistroFijo();
	nuevoRegistro->Registro::addCampo(registro.getMiIntID(), true);
	nuevoRegistro->Registro::addCampo(registro.getMiCharID(), true);
	nuevoRegistro->Registro::addCampo(registro.getMiInt(), false);
	
	try{
		this->recurso.almacenar(*nuevoRegistro);
	} catch (int) {
		throw ExcepcionMisDatos("No se pudo agregar registro");
	}
	delete nuevoRegistro;
}

void MisDatos::agregarRegistroArchivo3(MiRegistroTexto registro) throw (ExcepcionMisDatos){
	RegistroFijo* nuevoRegistro = new RegistroFijo();
	nuevoRegistro->addCampo(registro.getTexto(), false, registro.getTexto().size());
	
	try{
		this->recurso.almacenar(*nuevoRegistro);
	} catch (int) {
		throw ExcepcionMisDatos("");
	}
	delete nuevoRegistro;
}

void MisDatos::eliminarRegistroArchivo1(std::string clave) throw (ExcepcionMisDatos){
	try{
		list<string> claves;
		claves.push_back(clave);
		this->recurso.borrar(claves);
	} catch (int) {
		throw ExcepcionMisDatos("");
	}	
}

void MisDatos::eliminarRegistroArchivo2(int claveInt, char claveChar) throw (ExcepcionMisDatos){
	try{
		list<string> claves;
		char* tmp;
		sprintf(tmp, "%d", claveInt);
		claves.push_back(string(tmp));
		claves.push_back(string((char*) claveChar));
		this->recurso.borrar(claves);
	} catch (int) {
		throw ExcepcionMisDatos("");
	}	
}

void MisDatos::modificarRegistroArchivo1(MiRegistroVariable registro) throw (ExcepcionMisDatos){
	RegistroVariable* nuevoRegistro = new RegistroVariable();
	nuevoRegistro->addCampo(registro.getMiStringID(), true);
	nuevoRegistro->Registro::addCampo(registro.getMiInt(), false);
	nuevoRegistro->addCampo(registro.getMiLista(), registro.getCantidadElementosLista());
	
	this->recurso.modificar(*nuevoRegistro);
	
	delete nuevoRegistro;

}

void MisDatos::modificarRegistroArchivo2(MiRegistroFijo registro) throw (ExcepcionMisDatos){
	RegistroFijo* nuevoRegistro = new RegistroFijo();
	nuevoRegistro->Registro::addCampo(registro.getMiIntID(), true);
	nuevoRegistro->Registro::addCampo(registro.getMiCharID(), true);
	nuevoRegistro->Registro::addCampo(registro.getMiInt(), false);
	
	this->recurso.modificar(*nuevoRegistro);
}

MiRegistroVariable MisDatos::obtenerRegistroArchivo1(std::string clave) throw (ExcepcionMisDatos){
	
	try{
		list<string> claves;
		claves.push_back(clave);
		Registro respuesta = this->recurso.buscar(claves);
		string miString((char*) respuesta.getCampo());
		int miInt = *((int*)respuesta.getCampo());
		int tamLista = respuesta.getCantidadCampo();
		int* lista = *((int**)respuesta.getCampo());
		
		MiRegistroVariable registro(miString, miInt, lista, tamLista);
		
		return registro;		
	} catch (int) {
		throw ExcepcionMisDatos("");
	}
}

MiRegistroFijo MisDatos::obtenerRegistroArchivo2(int claveInt, char claveChar) throw (ExcepcionMisDatos){
	
	try{
		list<string> claves;
		char* tmp;
		sprintf(tmp, "%d", claveInt);
		claves.push_back(string(tmp));
		claves.push_back(string((char*) claveChar));

		Registro respuesta = this->recurso.buscar(claves);
		int miIntID = *((int*) respuesta.getCampo());
		char miCharID = *((char*) respuesta.getCampo());
		int miInt = *((int*) respuesta.getCampo());
		MiRegistroFijo registro(miIntID, miCharID, miInt);
		return registro;		
	} catch (int) {
		throw ExcepcionMisDatos("");
	}
}

void MisDatos::mostrarContenidoBufferArchivo1(){
	recurso.imprimirBuffer();
}

void MisDatos::mostrarContenidoBufferArchivo2(){
	recurso.imprimirBuffer();
}

void MisDatos::mostrarIndiceArchivo1(){
	recurso.imprimirIndice();
}

void MisDatos::mostrarIndiceArchivo2(){
	recurso.imprimirIndice();
}

void MisDatos::mostrarDatosArchivo1(){
	recurso.imprimirArchivo();
}

void MisDatos::mostrarDatosArchivo2(){
	recurso.imprimirArchivo();
}

void MisDatos::cerrarArchivo1(){
	recurso.cerrar();
}

void MisDatos::cerrarArchivo2(){
	recurso.cerrar();
}

void MisDatos::cerrarArchivo3(){
	recurso.cerrar();
}

#endif /*MISDATOS_H_*/
